Proper connect_port
[juce-lv2.git] / juce / source / extras / the jucer / src / model / paintelements / jucer_PaintElementImage.h
blob0cd262847cd2277695bf42700221511698ba4a6d
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_PAINTELEMENTIMAGE_JUCEHEADER__
27 #define __JUCER_PAINTELEMENTIMAGE_JUCEHEADER__
29 #include "../jucer_PaintRoutine.h"
30 #include "../../properties/jucer_FilePropertyComponent.h"
31 #include "jucer_ImageResourceProperty.h"
32 #include "jucer_PaintElementUndoableAction.h"
35 //==============================================================================
36 /**
38 class PaintElementImage : public PaintElement
40 public:
41 enum StretchMode
43 stretched = 0,
44 proportional = 1,
45 proportionalReducingOnly = 2
48 //==============================================================================
49 PaintElementImage (PaintRoutine* owner)
50 : PaintElement (owner, "Image"),
51 opacity (1.0),
52 mode (stretched)
56 ~PaintElementImage()
60 //==============================================================================
61 const Drawable* getDrawable()
63 JucerDocument* const document = getDocument();
65 if (document != 0)
66 return document->getResources().getDrawable (resourceName);
68 return 0;
71 void draw (Graphics& g, const ComponentLayout* layout, const Rectangle<int>& parentArea)
73 const Rectangle<int> r (position.getRectangle (parentArea, layout));
75 const Drawable* const image = getDrawable();
77 if (image != 0)
79 image->drawWithin (g, r.toFloat(),
80 mode == stretched ? RectanglePlacement::stretchToFit
81 : (mode == proportionalReducingOnly ? (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize)
82 : RectanglePlacement::centred),
83 (float) opacity);
85 else
87 g.setColour (Colours::grey.withAlpha (0.5f));
88 g.fillRect (r);
90 g.setColour (Colours::black);
91 g.drawText ("(image missing)",
92 r.getX(), r.getY(), r.getWidth(), r.getHeight(),
93 Justification::centred, true);
97 //==============================================================================
98 void getEditableProperties (Array <PropertyComponent*>& properties)
100 PaintElement::getEditableProperties (properties);
102 properties.add (new ImageElementResourceProperty (this));
103 properties.add (new StretchModeProperty (this));
104 properties.add (new OpacityProperty (this));
105 properties.add (new ResetSizeProperty (this));
108 void fillInGeneratedCode (GeneratedCode& code, String& paintMethodCode)
110 String r;
112 if (opacity > 0)
114 if (dynamic_cast <const DrawableImage*> (getDrawable()) != 0)
116 const String imageVariable ("cachedImage_" + resourceName);
118 code.addImageResourceLoader (imageVariable, resourceName);
120 if (opacity >= 254.0 / 255.0)
121 r << "g.setColour (Colours::black);\n";
122 else
123 r << "g.setColour (Colours::black.withAlpha (" << valueToFloat (opacity) << "));\n";
125 String x, y, w, h;
126 positionToCode (position, getDocument()->getComponentLayout(), x, y, w, h);
128 if (mode == stretched)
130 r << "g.drawImage (" << imageVariable << ",\n "
131 << x << ", " << y << ", " << w << ", " << h
132 << ",\n 0, 0, "
133 << imageVariable << ".getWidth(), "
134 << imageVariable << ".getHeight());\n\n";
136 else
138 r << "g.drawImageWithin (" << imageVariable << ",\n "
139 << x << ", " << y << ", " << w << ", " << h
140 << ",\n ";
142 if (mode == proportionalReducingOnly)
143 r << "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize";
144 else
145 r << "RectanglePlacement::centred";
147 r << ",\n false);\n\n";
150 paintMethodCode += r;
152 else
154 if (resourceName.isNotEmpty())
156 const String imageVariable (L"drawable" + String (code.getUniqueSuffix()));
158 code.privateMemberDeclarations
159 << "Drawable* " << imageVariable << ";\n";
161 code.constructorCode
162 << imageVariable << " = Drawable::createFromImageData ("
163 << resourceName << ", " << resourceName << "Size);\n";
165 code.destructorCode
166 << "deleteAndZero (" << imageVariable << ");\n";
168 if (opacity >= 254.0 / 255.0)
169 r << "g.setColour (Colours::black);\n";
170 else
171 r << "g.setColour (Colours::black.withAlpha (" << valueToFloat (opacity) << "));\n";
173 String x, y, w, h;
174 positionToCode (position, code.document->getComponentLayout(), x, y, w, h);
176 r << "jassert (" << imageVariable << " != 0);\n"
177 << "if (" << imageVariable << " != 0)\n "
178 << imageVariable << "->drawWithin (g, "
179 << x << ", " << y << ", " << w << ", " << h
180 << ",\n"
181 << String::repeatedString (" ", imageVariable.length() + 18)
182 << (mode == stretched ? "RectanglePlacement::stretchToFit"
183 : (mode == proportionalReducingOnly ? "RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize"
184 : "RectanglePlacement::centred"))
185 << ", " << valueToFloat (opacity)
186 << ");\n\n";
188 paintMethodCode += r;
190 else
192 jassertfalse // this resource isn't valid!
198 //==============================================================================
199 class SetResourceAction : public PaintElementUndoableAction <PaintElementImage>
201 public:
202 SetResourceAction (PaintElementImage* const element, const String& newResource_)
203 : PaintElementUndoableAction <PaintElementImage> (element),
204 newResource (newResource_)
206 oldResource = element->getResource();
209 bool perform()
211 showCorrectTab();
212 getElement()->setResource (newResource, false);
213 return true;
216 bool undo()
218 showCorrectTab();
219 getElement()->setResource (oldResource, false);
220 return true;
223 private:
224 String newResource, oldResource;
227 void setResource (const String& newName, const bool undoable)
229 if (resourceName != newName)
231 if (undoable)
233 perform (new SetResourceAction (this, newName),
234 "Change image resource");
236 else
238 resourceName = newName;
239 changed();
243 repaint();
246 const String getResource() const
248 return resourceName;
251 //==============================================================================
252 class SetOpacityAction : public PaintElementUndoableAction <PaintElementImage>
254 public:
255 SetOpacityAction (PaintElementImage* const element, const double newOpacity_)
256 : PaintElementUndoableAction <PaintElementImage> (element),
257 newOpacity (newOpacity_)
259 oldOpacity = element->getOpacity();
262 bool perform()
264 showCorrectTab();
265 getElement()->setOpacity (newOpacity, false);
266 return true;
269 bool undo()
271 showCorrectTab();
272 getElement()->setOpacity (oldOpacity, false);
273 return true;
276 private:
277 double newOpacity, oldOpacity;
280 void setOpacity (double newOpacity, const bool undoable)
282 newOpacity = jlimit (0.0, 1.0, newOpacity);
284 if (opacity != newOpacity)
286 if (undoable)
288 perform (new SetOpacityAction (this, newOpacity),
289 "Change image opacity");
291 else
293 opacity = newOpacity;
294 changed();
299 double getOpacity() const throw() { return opacity; }
301 //==============================================================================
302 static const char* getTagName() throw() { return "IMAGE"; }
304 void resetToImageSize()
306 const Drawable* const image = getDrawable();
308 if (image != 0 && getParentComponent() != 0)
310 const Rectangle<int> parentArea (((PaintRoutineEditor*) getParentComponent())->getComponentArea());
312 Rectangle<int> r (getCurrentBounds (parentArea));
313 Rectangle<float> bounds (image->getDrawableBounds());
315 r.setSize ((int) (bounds.getWidth() + 0.999f), (int) (bounds.getHeight() + 0.999f));
317 setCurrentBounds (r, parentArea, true);
321 //==============================================================================
322 class SetStretchModeAction : public PaintElementUndoableAction <PaintElementImage>
324 public:
325 SetStretchModeAction (PaintElementImage* const element, const StretchMode newValue_)
326 : PaintElementUndoableAction <PaintElementImage> (element),
327 newValue (newValue_)
329 oldValue = element->getStretchMode();
332 bool perform()
334 showCorrectTab();
335 getElement()->setStretchMode (newValue, false);
336 return true;
339 bool undo()
341 showCorrectTab();
342 getElement()->setStretchMode (oldValue, false);
343 return true;
346 private:
347 StretchMode newValue, oldValue;
350 StretchMode getStretchMode() const throw() { return mode; }
352 void setStretchMode (const StretchMode newMode, const bool undoable)
354 if (mode != newMode)
356 if (undoable)
358 perform (new SetStretchModeAction (this, newMode),
359 "Change image mode");
361 else
363 mode = newMode;
364 changed();
369 //==============================================================================
370 XmlElement* createXml() const
372 XmlElement* e = new XmlElement (getTagName());
373 position.applyToXml (*e);
374 e->setAttribute ("resource", resourceName);
375 e->setAttribute ("opacity", opacity);
376 e->setAttribute ("mode", (int) mode);
378 return e;
381 bool loadFromXml (const XmlElement& xml)
383 if (xml.hasTagName (getTagName()))
385 position.restoreFromXml (xml, position);
386 resourceName = xml.getStringAttribute ("resource", String::empty);
387 opacity = xml.getDoubleAttribute ("opacity", 1.0);
388 mode = (StretchMode) xml.getIntAttribute ("mode", (int) stretched);
390 repaint();
391 return true;
393 else
395 jassertfalse
396 return false;
400 private:
401 String resourceName;
402 double opacity;
403 StretchMode mode;
405 //==============================================================================
406 class ImageElementResourceProperty : public ImageResourceProperty <PaintElementImage>
408 public:
409 ImageElementResourceProperty (PaintElementImage* const element_)
410 : ImageResourceProperty <PaintElementImage> (element_, "image source")
414 //==============================================================================
415 void setResource (const String& newName)
417 element->setResource (newName, true);
420 const String getResource() const
422 return element->getResource();
426 //==============================================================================
427 class OpacityProperty : public SliderPropertyComponent,
428 private ChangeListener
430 public:
431 OpacityProperty (PaintElementImage* const element_)
432 : SliderPropertyComponent ("opacity", 0.0, 1.0, 0.001),
433 element (element_)
435 element->getDocument()->addChangeListener (this);
438 ~OpacityProperty()
440 element->getDocument()->removeChangeListener (this);
443 void setValue (double newValue)
445 element->getDocument()->getUndoManager().undoCurrentTransactionOnly();
447 element->setOpacity (newValue, true);
450 double getValue() const
452 return element->getOpacity();
455 void changeListenerCallback (ChangeBroadcaster*)
457 refresh();
460 private:
461 PaintElementImage* const element;
464 class StretchModeProperty : public ChoicePropertyComponent,
465 private ChangeListener
467 public:
468 StretchModeProperty (PaintElementImage* const element_)
469 : ChoicePropertyComponent ("stretch mode"),
470 element (element_)
472 choices.add ("Stretched to fit");
473 choices.add ("Maintain aspect ratio");
474 choices.add ("Maintain aspect ratio, only reduce in size");
476 element->getDocument()->addChangeListener (this);
479 ~StretchModeProperty()
481 element->getDocument()->removeChangeListener (this);
484 void setIndex (int newIndex)
486 element->setStretchMode ((StretchMode) newIndex, true);
489 int getIndex() const
491 return (int) element->getStretchMode();
494 void changeListenerCallback (ChangeBroadcaster*)
496 refresh();
499 private:
500 PaintElementImage* const element;
503 class ResetSizeProperty : public ButtonPropertyComponent
505 public:
506 ResetSizeProperty (PaintElementImage* const element_)
507 : ButtonPropertyComponent ("reset", false),
508 element (element_)
512 void buttonClicked()
514 element->resetToImageSize();
517 const String getButtonText() const { return "reset to image size"; }
519 private:
520 PaintElementImage* const element;
525 #endif // __JUCER_PAINTELEMENTIMAGE_JUCEHEADER__